import sys
import os
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from pathlib import Path

class TextEditor(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.current_file = None
        self.auto_save_timer = QTimer(self)
        self.setup_autosave()
        self.load_settings()

    def init_ui(self):
        # 主文本编辑区域
        self.text_edit = QTextEdit()
        self.setCentralWidget(self.text_edit)
        
        # 初始化菜单栏
        self.create_menus()
        # 初始化工具栏
        self.create_toolbars()
        # 初始化状态栏
        self.create_statusbar()
        
        # 窗口设置
        self.setWindowTitle("PyEdit")
        self.setGeometry(100, 100, 800, 600)
        self.show()

    def create_menus(self):
        # 文件菜单
        file_menu = self.menuBar().addMenu("&文件")
        new_action = QAction(QIcon.fromTheme("document-new"), "新建", self)
        new_action.triggered.connect(self.new_file)
        open_action = QAction(QIcon.fromTheme("document-open"), "打开...", self)
        open_action.triggered.connect(self.open_file)
        self.recent_menu = file_menu.addMenu("最近文件")
        file_menu.addAction(new_action)
        file_menu.addAction(open_action)
        file_menu.addSeparator()
        
        save_action = QAction(QIcon.fromTheme("document-save"), "保存", self)
        save_action.triggered.connect(self.save_file)
        save_as_action = QAction("另存为...", self)
        save_as_action.triggered.connect(self.save_as_file)
        file_menu.addAction(save_action)
        file_menu.addAction(save_as_action)
        file_menu.addSeparator()
        
        exit_action = QAction("退出", self)
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)

        # 编辑菜单
        edit_menu = self.menuBar().addMenu("&编辑")
        undo_action = QAction(QIcon.fromTheme("edit-undo"), "撤销", self)
        undo_action.triggered.connect(self.text_edit.undo)
        redo_action = QAction(QIcon.fromTheme("edit-redo"), "重做", self)
        redo_action.triggered.connect(self.text_edit.redo)
        edit_menu.addAction(undo_action)
        edit_menu.addAction(redo_action)
        edit_menu.addSeparator()
        
        cut_action = QAction(QIcon.fromTheme("edit-cut"), "剪切", self)
        cut_action.triggered.connect(self.text_edit.cut)
        copy_action = QAction(QIcon.fromTheme("edit-copy"), "复制", self)
        copy_action.triggered.connect(self.text_edit.copy)
        paste_action = QAction(QIcon.fromTheme("edit-paste"), "粘贴", self)
        paste_action.triggered.connect(self.text_edit.paste)
        edit_menu.addAction(cut_action)
        edit_menu.addAction(copy_action)
        edit_menu.addAction(paste_action)
        edit_menu.addSeparator()
        
        find_action = QAction("查找/替换...", self)
        find_action.triggered.connect(self.show_find_dialog)
        edit_menu.addAction(find_action)

        # 格式菜单
        format_menu = self.menuBar().addMenu("&格式")
        font_action = QAction("字体...", self)
        font_action.triggered.connect(self.set_font)
        color_action = QAction("颜色...", self)
        color_action.triggered.connect(self.set_color)
        wrap_action = QAction("自动换行", self, checkable=True)
        wrap_action.triggered.connect(self.toggle_wrap)
        format_menu.addAction(font_action)
        format_menu.addAction(color_action)
        format_menu.addAction(wrap_action)

        # 视图菜单
        view_menu = self.menuBar().addMenu("&视图")
        self.theme_menu = view_menu.addMenu("主题")
        self.create_theme_actions()
        zoom_in_action = QAction("放大", self)
        zoom_in_action.triggered.connect(self.zoom_in)
        zoom_out_action = QAction("缩小", self)
        zoom_out_action.triggered.connect(self.zoom_out)
        view_menu.addAction(zoom_in_action)
        view_menu.addAction(zoom_out_action)

    def create_toolbars(self):
        # 文件工具栏
        file_toolbar = self.addToolBar("文件")
        file_toolbar.addAction(QIcon.fromTheme("document-new"), "新建", self.new_file)
        file_toolbar.addAction(QIcon.fromTheme("document-open"), "打开", self.open_file)
        file_toolbar.addAction(QIcon.fromTheme("document-save"), "保存", self.save_file)
        
        # 编辑工具栏
        edit_toolbar = self.addToolBar("编辑")
        edit_toolbar.addAction(QIcon.fromTheme("edit-undo"), "撤销", self.text_edit.undo)
        edit_toolbar.addAction(QIcon.fromTheme("edit-redo"), "重做", self.text_edit.redo)
        edit_toolbar.addSeparator()
        edit_toolbar.addAction(QIcon.fromTheme("edit-cut"), "剪切", self.text_edit.cut)
        edit_toolbar.addAction(QIcon.fromTheme("edit-copy"), "复制", self.text_edit.copy)
        edit_toolbar.addAction(QIcon.fromTheme("edit-paste"), "粘贴", self.text_edit.paste)
        
        # 格式工具栏
        format_toolbar = self.addToolBar("格式")
        format_toolbar.addAction("字体", self.set_font)
        format_toolbar.addAction("颜色", self.set_color)

    def create_statusbar(self):
        self.status = self.statusBar()
        self.position_label = QLabel()
        self.status.addPermanentWidget(self.position_label)
        self.text_edit.cursorPositionChanged.connect(self.update_status)

    def setup_autosave(self):
        self.auto_save_timer.timeout.connect(self.auto_save)
        self.auto_save_timer.start(30000)  # 30秒自动保存

    def new_file(self):
        self.text_edit.clear()
        self.current_file = None

    def open_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self)
        if file_path:
            self.load_file(file_path)

    def save_file(self):
        if self.current_file:
            self.save_to_file(self.current_file)
        else:
            self.save_as_file()

    def save_as_file(self):
        file_path, _ = QFileDialog.getSaveFileName(self)
        if file_path:
            self.save_to_file(file_path)
            self.current_file = file_path

    def load_file(self, file_path):
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                self.text_edit.setText(f.read())
            self.current_file = file_path
            self.add_recent_file(file_path)
        except Exception as e:
            QMessageBox.warning(self, "错误", f"无法打开文件：{str(e)}")

    def save_to_file(self, file_path):
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(self.text_edit.toPlainText())
            self.status.showMessage(f"文件已保存：{file_path}", 5000)
        except Exception as e:
            QMessageBox.warning(self, "错误", f"保存文件失败：{str(e)}")

    def show_find_dialog(self):
        find_dialog = QDialog(self)
        find_dialog.setWindowTitle("查找/替换")
        
        find_label = QLabel("查找:")
        self.find_field = QLineEdit()
        replace_label = QLabel("替换:")
        self.replace_field = QLineEdit()
        
        find_button = QPushButton("查找下一个")
        replace_button = QPushButton("替换")
        replace_all_button = QPushButton("全部替换")
        
        layout = QVBoxLayout()
        layout.addWidget(find_label)
        layout.addWidget(self.find_field)
        layout.addWidget(replace_label)
        layout.addWidget(self.replace_field)
        layout.addWidget(find_button)
        layout.addWidget(replace_button)
        layout.addWidget(replace_all_button)
        
        find_button.clicked.connect(self.find_text)
        replace_button.clicked.connect(self.replace_text)
        replace_all_button.clicked.connect(self.replace_all)
        
        find_dialog.setLayout(layout)
        find_dialog.show()

    def find_text(self):
        text = self.find_field.text()
        if self.text_edit.find(text):
            self.text_edit.setFocus()
        else:
            QMessageBox.information(self, "查找", "已到达文档末尾")

    def replace_text(self):
        cursor = self.text_edit.textCursor()
        if cursor.selectedText() == self.find_field.text():
            cursor.insertText(self.replace_field.text())
        self.find_text()

    def replace_all(self):
        self.text_edit.setText(self.text_edit.toPlainText().replace(
            self.find_field.text(), self.replace_field.text()))

    def set_font(self):
        font, ok = QFontDialog.getFont(self.text_edit.font(), self)
        if ok:
            self.text_edit.setFont(font)

    def set_color(self):
        color = QColorDialog.getColor()
        if color.isValid():
            self.text_edit.setTextColor(color)

    def toggle_wrap(self, checked):
        if checked:
            self.text_edit.setLineWrapMode(QTextEdit.LineWrapMode.WidgetWidth)
        else:
            self.text_edit.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap)

    def create_theme_actions(self):
        themes = {
            "默认": "",
            "深色": """
                QTextEdit { background-color: #333; color: #FFF; }
                QMainWindow { background-color: #444; }
            """
        }
        for theme_name, style in themes.items():
            action = QAction(theme_name, self, checkable=True)
            action.triggered.connect(lambda _, s=style: self.setStyleSheet(s))
            self.theme_menu.addAction(action)

    def zoom_in(self):
        self.text_edit.zoomIn(1)

    def zoom_out(self):
        self.text_edit.zoomOut(1)

    def update_status(self):
        cursor = self.text_edit.textCursor()
        line = cursor.blockNumber() + 1
        col = cursor.columnNumber() + 1
        self.position_label.setText(f"行: {line} 列: {col}")

    def auto_save(self):
        if self.current_file and self.text_edit.document().isModified():
            self.save_to_file(self.current_file)

    def add_recent_file(self, file_path):
        recent_files = QSettings().value("recent_files", [])
        if file_path in recent_files:
            recent_files.remove(file_path)
        recent_files.insert(0, file_path)
        recent_files = recent_files[:10]  # 保留最近10个文件
        QSettings().setValue("recent_files", recent_files)
        self.update_recent_menu()

    def update_recent_menu(self):
        self.recent_menu.clear()
        recent_files = QSettings().value("recent_files", [])
        for file_path in recent_files:
            action = QAction(os.path.basename(file_path), self)
            action.setData(file_path)
            action.triggered.connect(lambda _, fp=file_path: self.load_file(fp))
            self.recent_menu.addAction(action)

    def load_settings(self):
        settings = QSettings()
        self.restoreGeometry(settings.value("geometry", QByteArray()))
        self.restoreState(settings.value("windowState", QByteArray()))
        self.update_recent_menu()

    def closeEvent(self, event):
        settings = QSettings()
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("windowState", self.saveState())
        if self.text_edit.document().isModified():
            reply = QMessageBox.question(
                self, "保存修改",
                "文档已修改，是否保存更改？",
                QMessageBox.StandardButton.Save | 
                QMessageBox.StandardButton.Discard |
                QMessageBox.StandardButton.Cancel)
            if reply == QMessageBox.StandardButton.Save:
                self.save_file()
            elif reply == QMessageBox.StandardButton.Cancel:
                event.ignore()
                return
        event.accept()


app = QApplication(sys.argv)
app.setApplicationName("WQTEdit")
app.setOrganizationName("WQTEdit")
editor = TextEditor()
sys.exit(app.exec())